﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using JulMar.Silverlight.Mvvm;
using JulMar.Siverlight.Helpers.Interactivity;
using MediaBrowserSL.RIA.MediaBrowserServiceReference;
using MediaBrowserSL.RIA.MvvmUtils;

namespace MediaBrowserSL.RIA.ViewModels
{
    /// <summary>
    /// Player Movie View Model
    /// </summary>
    public class PlayerMoviesViewModel : ViewModelBase
    {
        #region Private Member

        private Media currentMedia;
        private MediaElement mediaElement;
        private DispatcherTimer progressTimer;
        private string currentProgress;
        private MediaElementState CurrentState;

        private string statusPlayer;
        #endregion

        #region Public Member

        public Media CurrentMedia
        {
            get
            {
                return currentMedia;
            }
            set
            {

                currentMedia = value;
                OnPropertyChanged("CurrentMedia");
            }
        }

        public double TotalDuration
        {
            get
            {
                if (mediaElement != null)
                {
                    if (mediaElement.NaturalDuration.HasTimeSpan)
                    {
                        return mediaElement.NaturalDuration.TimeSpan.TotalSeconds;
                    }
                    else
                    {
                        return 0;
                    }
                }
                else
                {
                    return 0;
                }
            }
        }

        public double CurrentPosition
        {
            get
            {
                if (mediaElement != null)
                {
                    return mediaElement.Position.TotalSeconds;
                }
                else
                {
                    return 0;
                }
            }
            set
            {
                mediaElement.Position = new TimeSpan(0, 0, (int)value);
                OnPropertyChanged("CurrentProgress");
            }
        }

        public string CurrentProgress
        {
            get
            {
                return this.currentProgress;
            }
            set
            {
                this.currentProgress = value;
                OnPropertyChanged("CurrentProgress");
            }
        }

        public string StatusPlayer
        {
            get
            {
                return this.statusPlayer;
            }
            set
            {
                this.statusPlayer = value;
                OnPropertyChanged("StatusPlayer");
            }
        }

        #endregion

        #region Command

        public ICommand MediaOpenedCommand
        {
            get;
            private set;
        }

        public ICommand MediaFailedCommand
        {
            get;
            private set;
        }

        public DelegatingCommand PlayVideoCommand
        {
            get;
            private set;
        }

        public DelegatingCommand StopVideoCommand
        {
            get;
            private set;
        }

        public DelegatingCommand PauseVideoCommand
        {
            get;
            private set;
        }

        public ICommand CloseWindowCommand
        {
            get;
            private set;
        }

        public ICommand FullScreenCommand
        {
            get;
            private set;
        }

        #endregion

        #region Ctor

        public PlayerMoviesViewModel()
        {
            MediaOpenedCommand = new DelegatingCommand<EventInformation>(MediaOpened);
            MediaFailedCommand = new DelegatingCommand<EventInformation>(MediaFailed);
            PlayVideoCommand = new DelegatingCommand(PlayVideo, CanPlayVideo);
            StopVideoCommand = new DelegatingCommand(StopVideo, CanStopVideo);
            PauseVideoCommand = new DelegatingCommand(PauseVideo, CanPauseVideo);

            CloseWindowCommand = new DelegatingCommand<EventInformation>(CloseWindow);
            FullScreenCommand = new DelegatingCommand(OnFullScreen);

            this.progressTimer = new DispatcherTimer();
            this.progressTimer.Interval = TimeSpan.FromSeconds(1);
            this.progressTimer.Tick += this.ProgressTimer_Tick;
            CurrentProgress = "00:00:00 / 00:00:00";
            CurrentState = MediaElementState.Stopped;

            //Init Mediator
            RegisterWithMessageMediator();
        }
        
        #endregion

        #region Private Methods

        /// <summary>
        /// Chargement du Media
        /// </summary>
        /// <param name="param"></param>
        private void MediaOpened(EventInformation e)
        {
            MediaElement parmMediaElement = (MediaElement)e.CommandArgument;
            mediaElement = parmMediaElement;
            OnPropertyChanged("TotalDuration");
            PlayVideo();
        }

        /// <summary>
        /// Media Failed
        /// </summary>
        /// <param name="e"></param>
        private void MediaFailed(EventInformation e)
        {
            if (String.IsNullOrEmpty(CurrentMedia.UrlContent))
            {
                StatusPlayer = "Pas de fichier pour ce média !";
            }
            else
            {
                ExceptionRoutedEventArgs ex = e.EventParameter as ExceptionRoutedEventArgs;
                StatusPlayer = ex.ErrorException.Message;
            }
            RaiseCanExecuteChanged();
        }

        /// <summary>
        /// Play Video
        /// </summary>
        private void PlayVideo()
        {
            mediaElement.Play();
            progressTimer.Start();
            CurrentState = MediaElementState.Playing;
            RaiseCanExecuteChanged();
        }

        /// <summary>
        /// Can Play
        /// </summary>
        /// <returns></returns>
        private bool CanPlayVideo()
        {
            bool CanPlay = false;
            if (mediaElement != null)
            {
                if (CurrentState != MediaElementState.Playing)
                {
                    CanPlay = true;
                }
            }
            return CanPlay;
        }

        /// <summary>
        /// Pause Video
        /// </summary>
        private void PauseVideo()
        {
            if (CurrentState == MediaElementState.Playing)
            {
                if (mediaElement.CanPause)
                {
                    mediaElement.Pause();
                }
                else
                {
                    mediaElement.Stop();
                }
                progressTimer.Stop();
                CurrentState = MediaElementState.Paused;
            }
            else
            {
                mediaElement.Play();
                progressTimer.Start();
                CurrentState = MediaElementState.Playing;
            }
            RaiseCanExecuteChanged();
        }

        /// <summary>
        /// can pause
        /// </summary>
        /// <returns></returns>
        private bool CanPauseVideo()
        {
            bool CanPause = false;

            if (mediaElement != null)
            {
                if (CurrentState == MediaElementState.Playing)
                {
                    CanPause = true;
                }
            }

            return CanPause;
        }

        /// <summary>
        /// Stop Video
        /// </summary>
        private void StopVideo()
        {
            if (mediaElement != null)
            {
                progressTimer.Stop();
                mediaElement.Stop();
                CurrentProgress = "00:00 / 00:00";
                mediaElement.Position = new TimeSpan(0, 0, 0);
                OnPropertyChanged("CurrentPosition");
                CurrentState = MediaElementState.Stopped;
            }
            RaiseCanExecuteChanged();
        }

        /// <summary>
        /// can stop
        /// </summary>
        /// <returns></returns>
        private bool CanStopVideo()
        {
            bool CanStop = false;

            if (mediaElement != null)
            {
                CanStop = true;
            }

            return CanStop;
        }

        /// <summary>
        /// Progress Media
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ProgressTimer_Tick(object sender, EventArgs e)
        {
            if (mediaElement.NaturalDuration != Duration.Automatic)
            {
                CurrentProgress = string.Format(
                   "{0}:{1} / {2}:{3}",
                   Math.Floor(mediaElement.Position.TotalMinutes).ToString("00"),
                   mediaElement.Position.Seconds.ToString("00"),
                   Math.Floor(mediaElement.NaturalDuration.TimeSpan.TotalMinutes).ToString("00"),
                   mediaElement.NaturalDuration.TimeSpan.Seconds.ToString("00"));

                OnPropertyChanged("CurrentPosition");
            }
        }

        private void RaiseCanExecuteChanged()
        {
            if (PlayVideoCommand != null)
            {
                PlayVideoCommand.RaiseCanExecuteChanged();
                PauseVideoCommand.RaiseCanExecuteChanged();
                StopVideoCommand.RaiseCanExecuteChanged();
            }
        }

        /// <summary>
        /// Close Window => Stop Video and Progress Timer
        /// </summary>
        /// <param name="e"></param>
        private void CloseWindow(EventInformation e)
        {
            StopVideo();
        }

        /// <summary>
        /// Full Screen Video
        /// </summary>
        private void OnFullScreen()
        {
            Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
        }

        #endregion

        #region Public Methods
        /// <summary>
        /// LogOut
        /// </summary>
        [MessageMediatorTarget(MediatorMessages.PlayeMovie)]
        public void PlayeMovie(Media media)
        {
            CurrentMedia = media;
        }
        #endregion

    }
}
